#include <stdlib.h>

#ifdef _MSC_VER
#include "glut.h"
#else
#include <GL/gl.h>
#include <GL/glut.h>
#endif

#include "Data/CurveData.hpp"
#include "Data/Point2DData.hpp"
#include "View/CurveView.hpp"
#include "Command/CommandStack.hpp"
#include <vector>
#include "Graphics/OGLGraphics.hpp"
#include <fstream>

CurveView *cView = NULL;
GraphicsPtr cGraphics;

using Graph::Vertex;
using Graph::OGLGraphics;
using Graph::Color;

void Reshape(int width, int height)
{
    if (cGraphics != NULL)
    {
        cGraphics->setViewport(0, 0, width, height);
        cGraphics->setMatrixMode(Graphics::PROJECTION);
        cGraphics->loadIdentity();
        cGraphics->ortho(-1.0f, 11.0f, -1.0f, 11.0f, -0.1f, 0.1f);

        cGraphics->setMatrixMode(Graphics::MODELVIEW);
        cGraphics->loadIdentity();
    }
}

void Draw(void)
{
    static uint32_t blackColor = OGLGraphics::oglIntColor(0, 0, 0, 255);
    static Vertex zero(0.0f, 0.0f, 0.0f, blackColor);
    static Vertex topy(0.0f, 10.0f, 0.0f, blackColor);
    static Vertex topx(10.0f, 0.0f, 0.0f, blackColor);

    if (cGraphics != NULL)
    {
        cGraphics->clear();

        cGraphics->drawLine(zero, topy);
        cGraphics->drawLine(zero, topx);

        cView->draw();

        cGraphics->flush();
    }
}


int main(int argc, char *argv[])
{
    //Создаем CurveData
    CurveData *cData = new CurveData();
    ifstream input("tests/input1.txt");
    cData->load(input);

    //Создаем ConcretGraphics
    cGraphics = GraphicsPtr(new OGLGraphics());

    //Создаем CurveView
    cView = new CurveView(cGraphics.get(), cData);

    //Создаем CommandStack
    CommandStack cStack;

    //Тут как будто контроллер принимает запрос от пользователя, создает нужную команду и помещает ее в стек

    SimpleCommand<CurveView> *com = new SimpleCommand<CurveView>(cView, &CurveView::draw);

    cStack.addCommand(com);

    glutInit(&argc, argv);
    glutInitWindowSize(400, 300);
    glutInitWindowPosition(100, 100);

    glutInitDisplayMode(GLUT_RGB);
    glutCreateWindow("graphical-editor-oop");

    glutReshapeFunc(Reshape);
    glutDisplayFunc(Draw);
    cGraphics->clearColor(Color::white());

    glutMainLoop();

    return 0;
}
